package com.thinkit.bigdata.web.controller.sercutiry;

import com.thinkit.bigdata.core.feature.orm.mybatis.Page;
import com.thinkit.bigdata.core.util.StringUtil;
import com.thinkit.bigdata.web.model.config.SysArea;
import com.thinkit.bigdata.web.model.result.ConfigResult;
import com.thinkit.bigdata.web.model.result.Constants;
import com.thinkit.bigdata.web.model.result.HtmlResult;
import com.thinkit.bigdata.web.model.sec.*;
import com.thinkit.bigdata.web.service.sec.GroupService;
import com.thinkit.bigdata.web.service.sec.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.poi.ss.usermodel.*;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import sun.awt.SunHints;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by lihongli on 2018/9/17
 */
@Controller
@RequestMapping("group")
public class GroupController {

    private static Logger logger = Logger.getLogger(GroupController.class);

    private static final String AREAINIFO = "areaInfo";

    @Resource
    private GroupService groupService;

    @Resource
    private UserService userService;

    /**
     * 请求进入组织机构管理页面
     *
     * @param request
     * @return
     */
    @RequestMapping("/groups")
    public String showGroups(HttpServletRequest request, Model model) {
        logger.info("请求进入组织机构管理页面");
        // 取出区域信息
        SysArea area = (SysArea) request.getSession().getAttribute(AREAINIFO);
        if (null != area) {
            model.addAttribute("area", area);
        }
        return "SercutiryViews/group";
    }

    /**
     * 分页获取组织机构数据
     *
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/groupsByPage", method = RequestMethod.GET)
    public Page<SysGroup> groupsByPage(
            HttpServletRequest request,
            @RequestParam(value = "sortOrder") String sortOrder,
            @RequestParam(value = "sortName") String sortName,
            @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
            @RequestParam(value = "pageSize", defaultValue = "10") int pageSize,
            @RequestParam(value = "groupId", required = false) Long groupId,
            @RequestParam(value = "areaId", required = false) Long areaId,
            @RequestParam(value = "status", required = false) List<Integer> status,
            @RequestParam(value = "name", required = false) String name,
            @RequestParam(value = "type", required = false) List<Integer> type) {
        String logTxt = "【组织机构配置分页查询】";
        logger.info(logTxt + "查询条件: sortOrder=" + sortOrder);
        logger.info(logTxt + "查询条件: sortName=" + sortName);
        logger.info(logTxt + "查询条件: pageNum=" + pageNum);
        logger.info(logTxt + "查询条件: pageSize=" + pageSize);
        logger.info(logTxt + "查询条件: groupId=" + groupId);
        logger.info(logTxt + "查询条件: areaId=" + areaId);
        logger.info(logTxt + "查询条件: status=" + StringUtils.join(status, ","));
        logger.info(logTxt + "查询条件: name=" + name);
        logger.info(logTxt + "查询条件: type=" + type);
        // 查询条件设置
        SysGroupExample example = new SysGroupExample();
        SysGroupExample.Criteria criteria = example.createCriteria();
        // 要判断areaId是否为null 如果也为null 则判断当前登录用户所属区域
        if (areaId == null) {
            SysArea area = (SysArea) SecurityUtils.getSubject().getSession().getAttribute(AREAINIFO);
            if (area != null) criteria.andAreaidEqualTo((long) area.getId());// 说明不是集团人员
        } else {
            criteria.andAreaidEqualTo((long) areaId);
        }
        if (status != null && !status.isEmpty()) {
            criteria.andStatusIn(status);// 判断状态
        }
        if (StringUtil.isNotEmpty(name)) criteria.andNameLike("%" + name + "%");// 判断名称
        // 判断机构id 因为机构id不为null时涉及递归查询
        if (groupId != null) {
            // 机构id不为空 查询该id下所有子孙id
            List<Long> subGroupIdList = new ArrayList<>();
            subGroupIdList.add(groupId);
            List<Long> tmpList = new ArrayList<>();
            tmpList.add(groupId);
            while (!tmpList.isEmpty()) {
                Long id = tmpList.remove(0);
                criteria.andParentidEqualTo(id);
                List<SysGroup> groupList = groupService.selectByExample(example);
                // 查询完成后移除之前的查询条件
                criteria.getAllCriteria().remove(criteria.getAllCriteria().size() - 1);
                for (SysGroup group : groupList) {
                    subGroupIdList.add(group.getId());
                    tmpList.add(group.getId());
                }
            }
            // 查询
            criteria.andIdIn(subGroupIdList);
        }
        // 查询条件-机构类型设置，机构类型查询条件必须放在递归查询子机构之后，否则查询出来的子机构信息不全
        if (type != null && !type.isEmpty()) {
            criteria.andTypeIn(type);
        }
        example.setOrderByClause(sortName + " " + sortOrder);// 排序方式设置
        Page<SysGroup> page = new Page<>(pageNum, pageSize); // 分页设置
        groupService.selectByExample(page, example);
        logger.info(logTxt + "共计查询到" + page.getResult().size() + "条组织机构信息");
        return page;
    }

    /**
     * name唯一性校验（不同省份名称可以重复）
     *
     * @param request
     * @param name
     * @return
     */
    @ResponseBody
    @RequestMapping("/nameUniqueCheck")
    public ConfigResult nameUniqueCheck(HttpServletRequest request, @RequestParam("name") String name, @RequestParam("areaId") Long areaId) {
        String logTxt = "【组织机构name唯一性验证】";
        logger.info(logTxt + "name=" + name);
        SysGroupExample example = new SysGroupExample();
        example.createCriteria().andNameEqualTo(name).andAreaidEqualTo(areaId);
        int count = groupService.countByExample(example);
        if (count > 0) {
            logger.info(logTxt + name + "已存在");
            return new ConfigResult(Constants.ERROR, "该名称已存在");
        } else {
            logger.info(logTxt + name + "校验通过");
            return new ConfigResult(Constants.SUCCESS, "√");
        }
    }

    /**
     * 添加组织机构
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/groupAdd", method = RequestMethod.POST)
    public ConfigResult groupAdd(HttpServletRequest request, SysGroup group) {
        String logTxt = "【组织机构新增】";
        logger.info(logTxt + "新增组织机构信息" + group.toString());
        SysArea area = (SysArea) SecurityUtils.getSubject().getSession().getAttribute(AREAINIFO);
        if (group.getAreaid() == null && area == null) {
            // 如果组织机构id为null 且为超管或集团人员 则说明要添加的为集团机构
            group.setAreaid(Constants.GROUP_AREAID);
            // 集团机构树下只允许有一个子节点 判断
            if (group.getParentid() == null) {
                SysGroupExample example = new SysGroupExample();
                example.createCriteria().andParentidIsNull().andAreaidEqualTo(Constants.GROUP_AREAID);
                if (groupService.countByExample(example) > 0) {
                    // 说明集团下已经有一个子节点了 不允许再添加了
                    return new ConfigResult(Constants.FAIL, "集团下不能再创建平级的机构");
                }
            }
        } else if (group.getAreaid() != null && area != null && group.getAreaid().intValue() != area.getId().intValue()) {
            // 如果为省份人员 且机构id不为空 传递过来的省份id与session中不相同时 则返回错误信息
            return new ConfigResult(Constants.FAIL, "新增的机构所属省份信息有误");
        }
        // 对机构名称增加校验
        SysGroupExample checkExample = new SysGroupExample();
        checkExample.createCriteria().andNameEqualTo(group.getName()).andAreaidEqualTo(group.getAreaid());
        int count = groupService.countByExample(checkExample);
        if (count > 0)
            return new ConfigResult(Constants.ERROR, "该机构名称已存在");
        // 获取当前登录用户信息
        User user = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER_INFO);
        // 设置创建者信息 同时初始化修改者信息
        group.setCreatetime(new Date());
        group.setCreateuserid(user.getId());
        group.setLastupdatetime(new Date());
        group.setLastupdateuserid(user.getId());
        // 添加
        try {
            int rowNum = groupService.insert(group);
            if (rowNum > 0) {
                logger.info(logTxt + "数据库成功插入" + rowNum + "条数据");
                return new ConfigResult(Constants.SUCCESS, "组织机构添加成功");
            } else {
                logger.info(logTxt + "组织机构添加失败");
                return new ConfigResult(Constants.FAIL, "组织机构添加失败");
            }
        } catch (Exception e) {
            logger.error(logTxt + "组织机构添加错误", e);
            return new ConfigResult(Constants.ERROR, "组织机构添加错误");
        }
    }

    /**
     * 根据主键获取组织机构信息
     *
     * @param id
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/groupGetByPK", method = RequestMethod.POST)
    public SysGroup groupGetByPK(HttpServletRequest request, @RequestParam("id") Long id) {
        logger.info("获取id为【" + id + "】的组织机构信息");
        return groupService.groupGetByPK(id);
    }

    /**
     * 修改机构信息
     *
     * @param request
     * @param group
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/groupUpdate", method = RequestMethod.POST)
    public ConfigResult groupUpdate(HttpServletRequest request, SysGroup group) {
        String logTxt = "【修改组织机构】";
        logger.info(logTxt + group.toString());
        // 获取登录者信息 并设置修改信息
        User user = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER_INFO);
        group.setLastupdateuserid(user.getId());
        group.setLastupdatetime(new Date());
        try {
            int rowNum = groupService.update(group);
            if (rowNum > 0) {
                logger.info(logTxt + "数据库成功修改" + rowNum + "条数据");
                return new ConfigResult(Constants.SUCCESS, "组织机构修改成功");
            } else {
                logger.info(logTxt + "组织机构修改失败");
                return new ConfigResult(Constants.FAIL, "组织机构修改失败");
            }
        } catch (Exception e) {
            logger.error(logTxt + "组织机构修改错误", e);
            return new ConfigResult(Constants.ERROR, "组织机构修改错误");
        }
    }

    /**
     * 批量删除组织机构信息
     *
     * @param request
     * @param idList
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/groupDeleteBatch", method = RequestMethod.POST)
    public ConfigResult groupDeleteBatch(HttpServletRequest request, @RequestParam("idList") List<Long> idList) {
        String logTxt = "【组织机构批量删除】";
        logger.info(logTxt + "要删除的组织机构数量为：" + idList.size());
        if (!idList.isEmpty()) {
            try {
                int rowNum = groupService.groupDeleteBatch(idList);
                if (rowNum > 0) {
                    logger.info(logTxt + "组织机构批量删除" + rowNum + "条");
                    return new ConfigResult(Constants.SUCCESS, "批量删除成功");
                } else {
                    logger.info(logTxt + "组织机构批量删除失败");
                    return new ConfigResult(Constants.FAIL, "批量删除失败");
                }
            } catch (Exception e) {
                logger.error(logTxt + "组织机构批量删除错误", e);
                return new ConfigResult(Constants.ERROR, "批量删除错误");
            }
        } else {
            logger.info(logTxt + "未选择要删除的组织机构");
            return new ConfigResult(Constants.WARNING, "未选择要删除的组织机构");
        }
    }

    /**
     * 单个启用/停用
     *
     * @param request
     * @param id
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/statusSingle", method = RequestMethod.POST)
    public ConfigResult statusSingle(HttpServletRequest request, @RequestParam("id") Long id, @RequestParam("status") Integer status) {
        // 判断操作类型是启用还是停用
        String opType = Constants.getStatusName(status);
        String logTxt = "【组织机构" + opType + "】";
        logger.info(logTxt + "修改的组织机构id为：" + id);
        // 设置修改值
        User user = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER_INFO);
        SysGroup group = new SysGroup();
        group.setStatus(status);
        group.setLastupdatetime(new Date());
        group.setLastupdateuserid(user.getId());
        try {
            int rowNum = groupService.statusSingle(group, id);
            if (rowNum > 0) {
                logger.info(logTxt + "成功修改" + rowNum + "条组织机构的状态");
                return new ConfigResult(Constants.SUCCESS, "组织机构状态修改成功");
            } else {
                logger.info(logTxt + "状态修改失败");
                return new ConfigResult(Constants.FAIL, "组织机构状态修改失败");
            }
        } catch (Exception e) {
            logger.error(logTxt + "状态修改错误", e);
            return new ConfigResult(Constants.ERROR, "组织机构状态修改错误");
        }
    }

    /**
     * 批量启用/停用
     *
     * @param request
     * @param idList
     * @param status
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/statusBatch", method = RequestMethod.POST)
    public ConfigResult statusBatch(HttpServletRequest request, @RequestParam("idList") List<Long> idList, @RequestParam("status") Integer status) {
        // 判断操作类型是启用还是停用
        String opType = Constants.getStatusName(status);
        String logTxt = "【组织机构批量" + opType + "】";
        logger.info(logTxt + "批量修改的组织机构数量为：" + idList.size());
        if (!idList.isEmpty()) {
            // 设置修改值
            User user = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER_INFO);
            SysGroup group = new SysGroup();
            group.setStatus(status);
            group.setLastupdatetime(new Date());
            group.setLastupdateuserid(user.getId());
            try {
                int rowNum = groupService.statusBatch(group, idList);
                if (rowNum > 0) {
                    logger.info(logTxt + "成功修改" + rowNum + "条组织机构的状态");
                    return new ConfigResult(Constants.SUCCESS, "组织机构状态批量修改成功");
                } else {
                    logger.info(logTxt + "状态修改失败");
                    return new ConfigResult(Constants.FAIL, "组织机构状态批量修改失败");
                }
            } catch (Exception e) {
                logger.error(logTxt + "状态修改错误", e);
                return new ConfigResult(Constants.ERROR, "组织机构状态批量修改错误");
            }
        } else {
            logger.info(logTxt + "未选择要修改的资源");
            return new ConfigResult(Constants.WARNING, "未选择要修改的资源");
        }
    }

    /**
     * 获取整树的结构数据 包含坐席与质检节点
     *
     * @param areaId 要查询的省份id
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/showGroupTree", method = RequestMethod.GET)
    public List<JsTreeNode> showGroupTree(@RequestParam(required = false, value = "areaId") Integer areaId) {
        logger.info("查询组织机构树信息");
        // 判断查询单个省机构信息(某省用户登录、或超管/集团用户查询指定省份) 还是全部省信息(超管/集团用户不指定省份id)
        if (areaId == null) {
            // 判断登录用户是否属于某个省
            SysArea area = (SysArea) SecurityUtils.getSubject().getSession().getAttribute(AREAINIFO);
            if (area != null) {
                areaId = area.getId();
            }
        }
        return groupService.getTreeData(areaId).getChildren();
    }

    /**
     * 新增时机构树的数据获取 不包含坐席与质检节点
     *
     * @param areaId 要查询的省份id
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/showAddTree", method = RequestMethod.GET)
    public JsTreeNode showAddTree(@RequestParam(required = false, value = "areaId") Integer areaId) {
        logger.info("添加组织机构获取树机构信息");
        // 添加组织机构时 如果是省份用户登录，无论areaId是否为null，都查询所在省份机构信息；如果是集团/超管用户，传入null时，查询集团信息，非null时查询对应省份信息
        if (areaId == null) {
            // 判断登录用户是否属于某个省
            SysArea area = (SysArea) SecurityUtils.getSubject().getSession().getAttribute(AREAINIFO);
            if (area != null) {
                areaId = area.getId();
            } else {
                // 集团/超管用户，传入null 设置查询集团机构信息
                areaId = Constants.GROUP_AREAID.intValue();
            }
        }
        // 获取子节点信息
        return groupService.getAddTreeData(areaId);
    }

    /**
     * 修改树数据获取
     *
     * @param areaId  省份id
     * @param groupId 机构id
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/showEditTree", method = RequestMethod.GET)
    public JsTreeNode showEditTree(@RequestParam(required = false, value = "areaId") Integer areaId, @RequestParam(value = "groupId") Long groupId) {
        logger.info("修改组织机构获取树机构信息");
        if (areaId == null) {
            // 判断登录用户是否属于某个省
            SysArea area = (SysArea) SecurityUtils.getSubject().getSession().getAttribute(AREAINIFO);
            if (area == null) {
                // 集团/超管用户，传入null 设置查询集团机构信息
                areaId = Constants.GROUP_AREAID.intValue();
            } else {
                areaId = area.getId();
            }
        }
        return groupService.getEditTreeData(areaId, groupId);
    }

    /**
     * 根据id判断id对应的机构是不是质检组
     * 如果是，则查询并返回当前质检组所在省份的坐席组
     * 如果否，则返回null
     *
     * @param request
     * @param id
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/showSeatGroupById", method = RequestMethod.POST)
    public List<SysGroup> showSeatGroupById(HttpServletRequest request, @RequestParam("id") Long id) {
        List<SysGroup> groupList = new ArrayList<>();
        // 先根据id获取id对应的组织机构信息
        logger.info("获取id为" + id + "组织机构信息");
        SysGroup group = groupService.groupGetByPK(id);
        if (group.getType() != 1) {
            return groupList;
        }
        // 获取省份id
        Long areaId = group.getAreaid();
        logger.info("获取某省份下所有坐席组信息【areaId=" + areaId + "】");
        SysGroupExample example = new SysGroupExample();
        SysGroupExample.Criteria criteria = example.createCriteria();
        if (areaId != null) {
            criteria.andAreaidEqualTo(areaId);
        }
        criteria.andTypeEqualTo(0);// type=0为坐席
        return groupService.selectByExample(example);
    }

    /**
     * 获取某省份下所有坐席组信息
     * 质检员只返回他自己能看到的坐席班组 运营管理返回所有坐席班组
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/selectSeatGroup", method = RequestMethod.POST)
    public List<SysGroup> selectSeatGroup(HttpServletRequest request, Long areaId) {
        logger.info("获取某省份下所有坐席组信息【areaId=" + areaId + "】");
        // 判断当前登录人身份信息：质检员只返回他自己能看到的班组 运营管理返回所有
        User user = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER_INFO);
        if (user.getGroupid() == null || (user.getGroupid() != null && user.getGroup().getType().intValue() == 2)) {
            // 运营管理人员 或超管
            SysGroupExample example = new SysGroupExample();
            SysGroupExample.Criteria criteria = example.createCriteria();
            if (areaId != null) {
                criteria.andAreaidEqualTo(areaId);
            }
            criteria.andTypeEqualTo(0);// type=0为坐席
            return groupService.selectByExample(example);
        } else {
            if (user.getGroup().getType().intValue() == 1) {
                // 质检 根据质检组id查询其所有管辖的坐席组信息
                return groupService.selectSeatGroupByQcGroupId(user.getGroupid(), user.getId());
            }
            // 坐席人员 返回自己的组
            List<SysGroup> result = new ArrayList<>();
            result.add(user.getGroup());
            return result;
        }
    }

    /**
     * 根据组织机构id查询未经授权的坐席组信息（包含坐席组的父级机构信息）
     *
     * @param groupId
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/selectUnAuthSeatGroup", method = RequestMethod.GET)
    public List<GroupAuthDto> selectUnAuthSeatGroupByGroupId(@RequestParam("groupId") Long groupId) {
        // 校验groupId是不是自己省份的 返回值为null说明不是 不返回数据
        Long areaId = checkGroupIdAndReturnAreaId(groupId);
        if (areaId == null)
            return null;
        return groupService.selectUnAuthSeatGroupByGroupId(groupId, areaId);
    }

    /**
     * 根据组织机构id查询已授权的坐席组信息（包含坐席组的父级机构信息）
     *
     * @param groupId
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/selectAuthSeatGroup", method = RequestMethod.GET)
    public List<GroupAuthDto> selectAuthSeatGroupByGroupId(@RequestParam("groupId") Long groupId) {
        // 校验groupId是不是自己省份的 返回值为null说明不是 不返回数据
        Long areaId = checkGroupIdAndReturnAreaId(groupId);
        if (areaId == null)
            return null;
        return groupService.selectAuthSeatGroupByGroupId(groupId);
    }

    /**
     * 根据用户id、组织机构id查询未经授权的坐席组信息（包含坐席组的父级机构信息）
     * 查询：1.所在组设置的坐席组信息；2.个人设置的坐席组信息
     */
    @ResponseBody
    @RequestMapping(value = "/receiveUnAuthSeatGroup", method = RequestMethod.GET)
    public List<GroupAuthDto> receiveUnAuthSeatGroup(@RequestParam("userId") Long userId, @RequestParam("groupId") Long groupId) {
        // 校验groupId是不是自己省份的 返回值为null说明不是 不返回数据
        Long areaId = checkGroupIdAndReturnAreaId(groupId);
        if (areaId == null)
            return null;
        return groupService.receiveUnAuthSeatGroup(userId, groupId, areaId);
    }

    /**
     * 根据用户id、组织机构id查询已授权的坐席组信息（包含坐席组的父级机构信息）
     * 查询：1.所在组设置的坐席组信息；2.个人设置的坐席组信息
     */
    @ResponseBody
    @RequestMapping(value = "/receiveAuthSeatGroup", method = RequestMethod.GET)
    public List<GroupAuthDto> receiveAuthSeatGroup(@RequestParam("userId") Long userId, @RequestParam("groupId") Long groupId) {
        // 校验groupId是不是自己省份的 返回值为null说明不是 不返回数据
        Long areaId = checkGroupIdAndReturnAreaId(groupId);
        if (areaId == null)
            return null;
        return groupService.receiveAuthSeatGroup(userId, groupId);
    }

    /**
     * 获取某组织机构已选择的坐席组信息
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/selectedSeat", method = RequestMethod.POST)
    public QcRelationDto selectedSeat(HttpServletRequest request, Long qcGroupId) {
        logger.info("获取某质检组下所有坐席组信息【qcGroupId=" + qcGroupId + "】");
        return groupService.selectedSeat(qcGroupId);
    }

    /**
     * 质检组坐席组关系设定
     *
     * @param request
     * @param qcRelation
     * @return
     */
    @ResponseBody
    @RequestMapping("/qcRelationSave")
    public ConfigResult qcRelationSave(HttpServletRequest request, QcRelationDto qcRelation) {
        String logTxt = "【质检组坐席组关系设定】";
        logger.info(logTxt + qcRelation.toString());
        try {
            int rowNum = groupService.insertQcRelation(qcRelation);
            logger.info(logTxt + "质检组坐席组关系设定成功，成功写入数据" + rowNum + "条");
            return new ConfigResult(Constants.SUCCESS, "数据访问范围设定成功");
        } catch (Exception e) {
            logger.error(logTxt + "质检员坐席组关系设定错误", e);
            return new ConfigResult(Constants.ERROR, "数据访问范围设定错误");
        }
    }

    // 校验groupId是不是自己省份的 如果是的话 返回省份id 如果不是返回null 集团用户直接返回groupId对应的省份id
    private Long checkGroupIdAndReturnAreaId(Long groupId) {
        // 查询出来要授权的groupId对应省份id
        SysGroupExample example = new SysGroupExample();
        example.createCriteria().andIdEqualTo(groupId);
        List<SysGroup> groupList = groupService.selectByExample(example);
        if (groupList.isEmpty()) {
            return null;
        }
        // groupId对应的省份id
        Long areaId = groupList.get(0).getAreaid();
        // 用户所属省份信息
        SysArea area = (SysArea) SecurityUtils.getSubject().getSession().getAttribute(AREAINIFO);
        // 判断要修改的机构所属省份id与当前登录用户session中的省份id是否相同 正常情况下是不会出现这种情况的，不是很必要
        if (area != null && area.getId().intValue() != areaId.intValue()) {
            // 如果不同 说明groupId不是自己省份的 不允许查询出来数据
            return null;
        }
        return areaId;
    }

    /**
     * 批量导入组织机构
     *
     * @param request
     * @param uploadFile
     * @param areaId
     * @return
     */
    @ResponseBody
    @RequestMapping("/batchImportGroup")
    public ConfigResult batchImportGroup(
            HttpServletRequest request,
            @RequestParam("uploadFile") MultipartFile uploadFile,
            @RequestParam(required = false, value = "areaid") Long areaId) {
        String logTxt = "【批量导入组织机构信息】";
        logger.info(logTxt + "areaId= " + areaId);
        if (areaId == null) {
            areaId = Constants.GROUP_AREAID;
        }
        // 读取excel文件
        try (Workbook workbook = WorkbookFactory.create(uploadFile.getInputStream())) {
            // 读取第一个sheet表格
            Sheet sheet = workbook.getSheetAt(0);
            // 校验组织机构模板是否正确
            if (!checkTemplate(sheet)) {
                return new ConfigResult(Constants.ERROR, "请使用正确的模板进行导入");
            }
            List<SysGroup> groupList = new ArrayList<>();
            User loginUser = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER_INFO);
            Long loginUserId = loginUser.getId();
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                // 如果机构名称没有设置 则此行数据跳过不读取
                if (StringUtil.isEmpty(getStringCellValue(row.getCell(2)))) continue;
                // 封装数据到group对象中
                SysGroup group = new SysGroup();
                group.setRownum(i + 1);
                group.setAreaid(areaId);
                // 所属机构名称（上级机构名称）
                group.setParentname(getStringCellValue(row.getCell(0)));
                // 机构类型
                group.setType(getGroupType(getStringCellValue(row.getCell(1))));
                // 机构名称
                group.setName(getStringCellValue(row.getCell(2)));
                // 设置作者信息
                Date date = new Date();
                group.setCreateuserid(loginUserId);
                group.setCreatetime(date);
                group.setLastupdateuserid(loginUserId);
                group.setLastupdatetime(date);
                groupList.add(group);
            }
            // 批量添加用户 修改返回值类型 保存错误信息
            HtmlResult result = groupService.insertGroups(groupList);
            int rowNum = (int) result.getCount();
            int failNum = groupList.size() - rowNum;
            logger.info(logTxt + "成功批量导入组织机构" + rowNum + "个，" + failNum + "个导入失败");
            logger.info("【批量导入组织机构错误信息】" + result.getMsg());
            // 如果一个都没有导入成功 则返回导入失败信息
            if (rowNum == 0)
                return new ConfigResult(Constants.ERROR, "批量导入失败:" + result.getMsg());
            if (failNum == 0)
                return new ConfigResult(Constants.SUCCESS, "成功导入" + rowNum + "个");
            return new ConfigResult(Constants.SUCCESS, "成功导入" + rowNum + "个，" + failNum + "个导入失败;" + result.getMsg());
        } catch (Exception e) {
            logger.error(logTxt + "批量导入错误", e);
            return new ConfigResult(Constants.ERROR, "批量导入组织机构失败，请检查文件内容格式是否正确");
        }
    }

    // 校验导入时使用的模板是否正确
    private boolean checkTemplate(Sheet sheet) {
        // 取一行表头内容校验
        Row row = sheet.getRow(0);
        String[] title = {"上级组织机构", "部门类型", "部门名称"};
        for (int i = 0; i < title.length; i++) {
            if (!getStringCellValue(row.getCell(i)).equals(title[i])) {
                return false;
            }
        }
        return true;
    }

    // 对单元格的值统一处理 返回字符
    private String getStringCellValue(Cell cell) {
        if (cell == null) return "";
        if (CellType.NUMERIC == cell.getCellType()) {
            cell.setCellType(CellType.STRING);
        }
        return cell.getStringCellValue().trim();
    }

    // 对机构类型进行转换 坐席--0 质检--1 其他部门--2
    private Integer getGroupType(String type) {
        if ("坐席".equals(type)) {
            return 0;
        } else if ("质检".equals(type)) {
            return 1;
        } else {
            return 2;
        }
    }

    /**
     * 根据groupId查询其是否有子机构
     *
     * @param groupId
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/checkSubGroupNum", method = RequestMethod.GET)
    public Integer checkSubGroupNum(@RequestParam("groupId") Long groupId) {
        SysGroupExample example = new SysGroupExample();
        example.createCriteria().andParentidEqualTo(groupId);
        return groupService.countByExample(example);
    }

    /**
     * 检查某些机构下是否有用户
     *
     * @param idList
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "countUserInGroups", method = RequestMethod.GET)
    public Integer countUserInGroups(@RequestParam("idList") String idList) {
        UserExample example = new UserExample();
        String[] split = idList.split(",");
        List<Long> groupIdList = new ArrayList<>();
        for (String id : split) {
            selectSubGroupId(Long.valueOf(id), groupIdList);
        }
        example.createCriteria().andGroupidIn(groupIdList);
        return userService.countByExample(example);
    }

    // 传入某机构id 获取包含它在内的所有子机构
    private void selectSubGroupId(Long groupId, List<Long> groupIdList) {
        List<Long> tmpList = new ArrayList<>();
        groupIdList.add(groupId);
        tmpList.add(groupId);
        while (!tmpList.isEmpty()) {
            Long id = tmpList.remove(0);
            SysGroupExample example = new SysGroupExample();
            example.createCriteria().andParentidEqualTo(id);
            List<SysGroup> groupList = groupService.selectByExample(example);
            for (SysGroup group : groupList) {
                groupIdList.add(group.getId());
                tmpList.add(group.getId());
            }
        }
    }

    /**
     * 根据机构id查询对应省份code
     *
     * @param groupId
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/selectProvinceCodeByGroupId", method = RequestMethod.GET)
    public String selectProvinceCodeByGroupId(@RequestParam Long groupId) {
        SysArea area = groupService.selectAreaInfoByGroupId(groupId);
        return area == null ? "JT_" : area.getCode();
    }
}
